﻿using Futuret.Core.Utils.SM;
using NETCore.Encrypt;
using Org.BouncyCastle.Crypto.Signers;

namespace Futuret.Core.Utils;

/// <summary>
///     Author: Riva
///     Date: 2023/7/11 21:48
///     Description:  常用加密工具类
/// </summary>
public static class EncryptUitl
{
    #region HMACSHA256加密

    /// <summary>
    ///     HMACSHA256 加密
    /// </summary>
    /// <param name="password"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    public static string Hmacsha256Encryption(string password, string key)
    {
        return EncryptProvider.HMACSHA256(password, key);
    }

    /// <summary>
    ///     HMACSHA256 是否匹配
    /// </summary>
    /// <param name="passwordHash">加密后的字符串</param>
    /// <param name="securityStamp">加密盐</param>
    /// <param name="password">原字符串</param>
    /// <returns></returns>
    public static bool CheckHmacsha256Encryption(string passwordHash, string securityStamp, string password)
    {
        return EncryptProvider.HMACSHA256(password, securityStamp)
            .Equals(passwordHash, StringComparison.InvariantCultureIgnoreCase);
    }

    #endregion HMACSHA256加密

    #region MD5加密

    /// <summary>
    ///     MD5 加密
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public static string Md5Encryption(string password)
    {
        return EncryptProvider.Md5(password);
    }

    /// <summary>
    ///     MD5 是否匹配
    /// </summary>
    /// <param name="passwordHash">加密后的字符串</param>
    /// <returns></returns>
    public static bool CheckMd5Encryption(string passwordHash)
    {
        return EncryptProvider.Md5(passwordHash)
            .Equals(passwordHash, StringComparison.InvariantCultureIgnoreCase);
    }

    #endregion MD5加密

    #region RSA 加密

    /// <summary>
    ///     RSA 创建公钥|秘密
    /// </summary>
    /// <returns></returns>
    public static (string, string) CreateRsaKey(RsaSize rsaSize = RsaSize.R2048)
    {
        var rsaKey = EncryptProvider.CreateRsaKey(rsaSize);
        return (rsaKey.PublicKey, rsaKey.PrivateKey);
    }

    /// <summary>
    ///     RSA 生成签名
    /// </summary>
    /// <param name="rawStr">原文</param>
    /// <param name="privateKey">私钥</param>
    /// <returns></returns>
    public static string RsaSign(string rawStr, string privateKey)
    {
        return EncryptProvider.RSASign(rawStr, privateKey);
    }

    /// <summary>
    ///     RSA 验签
    /// </summary>
    /// <param name="rawStr">原文</param>
    /// <param name="signStr">签名</param>
    /// <param name="publicKey">公钥</param>
    /// <returns></returns>
    public static bool RsaVerify(string rawStr, string signStr, string publicKey)
    {
        return EncryptProvider.RSAVerify(rawStr, signStr, publicKey);
    }

    /// <summary>
    ///     RSA 加密
    /// </summary>
    /// <param name="publicKey">公钥</param>
    /// <param name="srcString">数据</param>
    /// <returns></returns>
    public static string RsaEncrypt(string publicKey, string srcString)
    {
        return EncryptProvider.RSAEncrypt(publicKey, srcString);
    }

    /// <summary>
    ///     解密
    /// </summary>
    /// <param name="privateKey">私钥</param>
    /// <param name="encryptedStr">加密的数据</param>
    /// <returns></returns>
    public static string RsaDecrypt(string privateKey, string encryptedStr)
    {
        return EncryptProvider.RSADecrypt(privateKey, encryptedStr);
    }

    #endregion RSA 加密

    #region Sm2

    /// <summary>
    /// 创建公钥私钥对
    /// </summary>
    /// <returns></returns>
    public static (string, string) CreateSm2Key()
    {
        SM2Util.GenerateKeyHex(out var publicKey, out var privateKey);
        return (publicKey, privateKey);
    }

    /// <summary>
    /// 返回验签
    /// </summary>
    /// <param name="publicKey"></param>
    /// <param name="privateKey"></param>
    /// <param name="encryed"></param>
    /// <returns></returns>
    public static string Sm2Sign(string publicKey, string privateKey, string encryed)
    {
        var sm2 = new SM2Util(publicKey, privateKey);
        return sm2.Sign(encryed);
    }

    /// <summary>
    /// Sm2验签
    /// </summary>
    /// <param name="encryed"></param>
    /// <param name="sing"></param>
    /// <param name="publicKey"></param>
    /// <param name="privateKey"></param>
    /// <returns></returns>
    public static bool Sm2VerifySign(string encryed, string sing, string publicKey, string privateKey)
    {
        var sm2 = new SM2Util(publicKey,privateKey);
        return sm2.VerifySign(encryed, sing);
    }

    /// <summary>
    /// 公钥加密明文
    /// </summary>
    /// <param name="plainText">明文</param>
    /// <param name="publicKey"></param>
    /// <returns>密文</returns>
    public static string Sm2Encrypt(string plainText,string publicKey, string privateKey)
    {
        var sm2 = new SM2Util(publicKey, privateKey);
        return sm2.Encrypt(plainText);
    }

    /// <summary>
    /// 私钥解密密文
    /// </summary>
    /// <param name="cipherText">密文</param>
    /// <param name="publicKey"></param>
    /// <param name="privateKey"></param>
    /// <returns>明文</returns>
    public static string Sm2Decrypt(string cipherText,string publicKey, string privateKey)
    {
        var sm2 = new SM2Util(publicKey, privateKey);
        return sm2.Decrypt(cipherText);
    }

    #endregion

    #region Sm4

    /// <summary>
    /// SM4ECB模式解密
    /// </summary>
    /// <param name="plainText">密文</param>
    /// <param name="key"></param>
    /// <returns>明文</returns>
    public static string Sm4DecryptEcb(string plainText,string key)
    {
        var sm4 = new Sm4Util(plainText);
        return sm4.Decrypt_ECB(plainText);
    }

    /// <summary>
    /// SM4ECB模式加密
    /// </summary>
    /// <param name="plainText"></param>
    /// <returns>密文</returns>
    public static string Sm4EncryptEcb(string plainText)
    {
        var sm4 = new Sm4Util(plainText);
        return sm4.Encrypt_ECB(plainText);
    }
    
    /// <summary>
    /// SM4ECB模式解密
    /// </summary>
    /// <param name="plainText">密文</param>
    /// <param name="key"></param>
    /// <returns>明文</returns>
    public static string Sm4DecryptCbc(string plainText,string key)
    {
        var sm4 = new Sm4Util(plainText);
        return sm4.Decrypt_CBC(plainText);
    }

    /// <summary>
    /// SM4ECB模式加密
    /// </summary>
    /// <param name="plainText"></param>
    /// <returns>密文</returns>
    public static string Sm4EncryptCbc(string plainText)
    {
        var sm4 = new Sm4Util(plainText);
        return sm4.Encrypt_CBC(plainText);
    }

    #endregion
}